// @ts-nocheck
/**
 * 手写 instanceOf
 */
// function _instanceOf(A, B) {
// 	let l = A
// 	while (l !== null) {
// 		const temp = Reflect.getPrototypeOf(l)
// 		if (temp === B.prototype) return true
// 		l = temp
// 	}
// 	return false
// }

// function inherit(p, s) {
// 	const temp = Object.create(p.prototype)
// 	s.prototype = temp
// 	temp.construct = s
// }
// function Parent(args) {
// 	this.name = args[0]
// 	this.age = args[1]
// }
// function Son(...args) {
// 	Parent.call(this, args)
// }
// inherit(Parent, Son)
// const s = new Son('lisi', 15)

// console.log(_instanceOf(s, Parent))
// console.log(s.age, s.name)
// console.dir(s);

/**
 * 手写 new 操作符
 * new 的 返回值
 * 1. 构造函数 返回是 对象 就返回对象
 * 2. 构造函数无返回值 或者返回 null  就返回 创建的对象
 */

// function myNew(_construct, ...args) {
// 	const obj = Object.create(_construct.prototype)
// 	let res = _construct.call(obj, ...args)
// 	var isObject = typeof res === 'object' && res !== null
// 	var isFunction = typeof res === 'function'
// 	if (isObject || isFunction) {
// 		return res
// 	}
// 	return obj
// }

// function F(name, age) {
// 	this.name = name
// 	this.age = age
// 	return undefined
// }

// const f = myNew(F, 'zhangsan', 15)
// const f2 = new F('zhangsan', 15)
// console.dir(f)
// console.dir(f2)

/**
 * 手写 call、apply、bind 函数
 */

// Function.prototype.myCall = function (context = window, ...args) {
// 	let fn = Symbol('fn')
// 	context[fn] = this
// 	const res = context[fn](...args)
// 	delete context[fn]
// 	return res
// }

// Function.prototype.myApply = function (context = window, arr) {
// 	const fn = Symbol('fn')
// 	context[fn] = this
// 	const res = context[fn](...arr)
// 	delete context[fn]
// 	return res
// }

// Function.prototype.myBind = function (context = window) {
// 	const fn = Symbol('fn')
// 	context[fn] = this
// 	return function (...args) {
// 		return context[fn].myApply(context, args)
// 	}
// }

// let obj = {}
// function sayName(age) {
// 	this.age = age
// 	console.log(age)
// }
// sayName.call(obj, 15)
// sayName.myCall(obj, 15)

// sayName.apply(obj, [15])
// sayName.myApply(obj, [15])

// sayName.bind(obj)(15)
// sayName.myBind(obj)(15)

/**
 * 手写深拷贝
 */

// function deepClone(object, hash = new WeakMap()) {
// 	if (hash.has(object)) return hash.get(object)
// 	const res = Array.isArray(object) ? [] : {}
// 	hash.set(object, res)
// 	for (const key in object) {
// 		if (Object.hasOwnProperty.call(object, key)) {
// 			const element = object[key]
// 			if (typeof element === 'object' && typeof element !== null) {
// 				res[key] = deepClone(element, hash)
// 			} else {
// 				res[key] = element
// 			}
// 		}
// 	}
// 	return res
// }

// let obj = {
// 	arr: [1, 2],
// 	address: {
// 		name: 'beijing',
// 	},
// }

// const p = deepClone(obj)
// p.arr.push(1222)
// p.next = p
// console.log(p)
// console.log(obj)

/**
 * 手写防抖 节流
 */

// function debounce(callback, time) {
// 	let timer = null
// 	return function (...args) {
// 		timer && clearInterval(timer)
// 		timer = setTimeout(() => {
// 			callback.apply(this, args)
// 		}, time)
// 	}
// }

// function throttle(callback, time) {
// 	let startTime = 0
// 	return function (...args) {
// 		let nowTime = Date.now()
// 		if (nowTime - startTime >= time) {
// 			callback.apply(this, args)
// 			startTime = nowTime
// 		}
// 	}
// }

/**
 * 手写  封装 Ajax
 */

// function request(url, method, params) {
// 	return new Promise((resolve, reject) => {
// 		const xhr = new XMLHttpRequest()
// 		xhr.open('GET', url, true)
// 		xhr.onreadystatechange = function (status) {
// 			if (xhr.readyState == 4) {
// 				if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 301) {
// 					const res = xhr.responseText
// 					resolve(JSON.stringify(res))
// 				} else {
// 					reject(JSON.stringify(xhr))
// 				}
// 			}
// 		}
// 		let data = method == 'GET' ? null : params
// 		xhr.send(data)
// 	})
// }

// request('https://api.github.com/users/ruanyf', 'GET')
// 	.then((res) => {
// 		console.log(JSON.parse(res))
// 	})
// 	.catch((err) => {
// 		console.log(err)
// 	})

/**
 *手写 封装 fetch
 */
// function fetchRequest(url, method, params) {
// 	let config = {
// 		method,
// 	}
// 	if (method.toUpperCase() === 'POST') {
// 		config.body = params
// 	}
// 	return new Promise((resolve, reject) => {
// 		fetch(url, config).then((response) => {
// 			if (response.ok) {
// 				resolve(response.json())
// 			} else {
// 				reject(response)
// 			}
// 		})
// 	})
// }

// fetchRequest('https://api.github.com/users/ruanyf', 'GET').then((res) => {
// 	console.log(res)
// })

/**
 * 手写 数组去重(完美版)
 */

// function uniqueArr(arr) {
// 	// let obj = {}
// 	// let res = []
// 	// for (let i = 0; i < arr.length; i++) {
// 	// 	const item = arr[i]
// 	// 	const prototype = Object.prototype.toString.call(item)
// 	// 	if (obj[prototype + item]) {
// 	// 		continue
// 	// 	} else {
// 	// 		res.push(arr[i])
// 	// 		obj[prototype + item] = true
// 	// 	}
// 	// }
// 	// return res
// 	let map = new Map()
// 	return arr.filter((item) => {
// 		const key = typeof item + item
// 		if (!map.has(key)) {
// 			return map.set(key, true)
// 		}
// 	})
// }
// let arrTest2 = [
// 	1,
// 	1,
// 	'true',
// 	'true',
// 	true,
// 	true,
// 	15,
// 	15,
// 	false,
// 	false,
// 	undefined,
// 	undefined,
// 	null,
// 	null,
// 	NaN,
// 	NaN,
// 	'NaN',
// 	0,
// 	0,
// 	'a',
// 	'a',
// 	{},
// 	{},
// ]
// console.log(uniqueArr(arrTest2))

/**
 * 手写 数组扁平
 */

// function flat(arr) {
// 	return arr.reduce((pre, cur) => {
// 		if (Array.isArray(cur)) {
// 			pre = [...pre, ...flat(cur)]
// 			return pre
// 		} else {
// 			return [...pre, cur]
// 		}
// 	}, [])
// }
// console.log('flat()', flat([1, [2, 3, [4, [5]]]]))

/**
 * 手写 数组乱序
 */

// function unOrder(arr = [1, 2, 3, 4, 5]) {
// 	let len = arr.length
// 	return arr.sort(() => Math.random() - 0.5)
// }
// console.log(unOrder())

/**
 * 手写 Promise.all()、Promise.race() 、 Promise.allsettled() 、Promise.any()
 *
 */

// Promise.all = function (promiseArr) {
// 	return new Promise((resolve, reject) => {
// 		if (!Array.isArray(promiseArr))
// 			return reject(new TypeError('Argument is not iterable'))
// 		if (!promiseArr.length) return resolve(promiseArr)
// 		let res = []
// 		promiseArr.forEach((item, index) => {
// 			if (item instanceof Promise) {
// 				Promise.resolve(item).then(
// 					(value) => {
// 						res.push(value)
// 						res.length == promiseArr.length && resolve(res)
// 					},
// 					(err) => reject(err)
// 				)
// 			} else {
// 				res[index] = item
// 				res.length == promiseArr.length && reject(res)
// 			}
// 		})
// 	})
// }

// Promise.allSettled = function (promiseArr) {
// 	return new Promise((resolve, reject) => {
// 		if (!Array.isArray(promiseArr))
// 			return reject(new TypeError('Arguments is not iterable'))
// 		if (!promiseArr.length) return resolve(promiseArr)
// 		let res = []
// 		promiseArr.forEach((item, index) => {
// 			Promise.resolve(item).then(
// 				(value) => {
// 					res[index] = {
// 						status: 'Fulfilled',
// 						value,
// 					}
// 					res.length === promiseArr.length && resolve(res)
// 				},
// 				(reason) => {
// 					res[index] = {
// 						status: 'rejected',
// 						reason,
// 					}
// 					res.length === promiseArr.length && resolve(res)
// 				}
// 			)
// 		})
// 	})
// }

// Promise.any = function (promiseArr) {
// 	return new Promise((resolve, reject) => {
// 		if (!Array.isArray(promiseArr))
// 			return reject(new TypeError('Arguments  is not  iterable'))
// 		if (!promiseArr.length) return reject(promiseArr)
// 		let res = []
// 		promiseArr.forEach((item) => {
// 			Promise.resolve(item).then(
// 				(value) => {
// 					resolve(value)
// 				},
// 				(reason) => {
// 					res.push(reason)
// 					res.length === promiseArr.length && reject(new AggregateError(res))
// 				}
// 			)
// 		})
// 	})
// }

// Promise.race = function (promiseArr) {
// 	return new Promise((resolve, reject) => {
// 		if (!Array.isArray(promiseArr))
// 			reject(new TypeError('Argument is not iterable'))
// 		if (promiseArr.length > 0) {
// 			promiseArr.forEach((item) => {
// 				Promise.resolve(item).then(resolve, reject)
// 			})
// 		}
// 	})
// }

/**
 * 手写 函数柯里化
 */
// function curry(fn) {
// 	function curried(...args) {
// 		let len = fn.length
// 		if (args.length >= len) {
// 			return fn.apply(this, args)
// 		} else {
// 			return function (...arr) {
// 				return curried.apply(this, [...args, ...arr])
// 			}
// 		}
// 	}
// 	return curried
// }
// function sum(x, y, z) {
// 	console.log(x + y + z)
// 	return x + y + z
// }
// var curryAdd = curry(sum)

// curryAdd(10, 20, 30)
// curryAdd(10, 20)(30)
// curryAdd(10)(20)(30)

/**
 * 手写 列表转树 树转链表
 */

// function toTree(arr) {
// 	let res = []
// 	let map = {}
// 	arr.forEach((el) => {
// 		map[el.id] = el
// 		if (el.pid === 0) {
// 			res.push(el)
// 		} else {
// 			const parent = map[el.pid]
// 			parent.children = parent.children || []
// 			parent.children.push(el)
// 		}
// 	})
// 	console.log(res)
// 	console.log(map)
// 	return res
// }
// function flatTree(arr) {
// 	let res = []
// 	function _(arr) {
// 		arr.forEach((item) => {
// 			if (item.children && item.children.length) {
// 				_(item.children)
// 			} else {
// 				if (item.children?.length === 0) delete item.children
// 				res.push(item)
// 			}
// 		})
// 	}
// 	_(arr)
// 	console.log(res)
// 	return res
// }

// const flatData = [
// 	{ id: 1, name: '首页', pid: 0, type: 1 },
// 	{ id: 2, name: '系统权限', pid: 0, type: 1 },
// 	{ id: 3, name: '角色管理', pid: 2, type: 2 },
// 	{ id: 6, name: '添加角色', pid: 3, type: 3 },
// 	{ id: 7, name: '修改角色', pid: 3, type: 3 },
// 	{ id: 8, name: '删除角色', pid: 3, type: 3 },
// 	{ id: 9, name: '配置权限', pid: 3, type: 3 },
// 	{ id: 4, name: '用户管理', pid: 2, type: 2 },
// 	{ id: 5, name: '权限管理', pid: 2, type: 2 },
// ]
// const treeData = [
// 	{
// 		id: 1,
// 		name: '首页',
// 		pid: 0,
// 		type: 1,
// 		children: [],
// 	},
// 	{
// 		id: 2,
// 		name: '系统权限',
// 		pid: 0,
// 		type: 1,
// 		children: [
// 			{
// 				id: 3,
// 				name: '角色管理',
// 				pid: 2,
// 				type: 2,
// 				children: [
// 					{
// 						id: 6,
// 						name: '添加角色',
// 						pid: 3,
// 						type: 3,
// 					},
// 					{
// 						id: 7,
// 						name: '修改角色',
// 						pid: 3,
// 						type: 3,
// 					},
// 					{
// 						id: 8,
// 						name: '删除角色',
// 						pid: 3,
// 						type: 3,
// 					},
// 					{
// 						id: 9,
// 						name: '配置权限',
// 						pid: 3,
// 						type: 3,
// 					},
// 				],
// 			},
// 			{
// 				id: 4,
// 				name: '用户管理',
// 				pid: 2,
// 				type: 2,
// 				children: [],
// 			},
// 			{
// 				id: 5,
// 				name: '权限管理',
// 				pid: 2,
// 				type: 2,
// 			},
// 		],
// 	},
// ]

// toTree(flatData)
// flatTree(treeData)

/**
 * 按要求组合数据结构(按照type实现分组效果)
 * [
 * 	{
 * 		type:0, values:[ { name:1,type:0 },{ name:2,type:0 }]
 * 	},
 *  {
 *   type:1, values:[ { name:3,type:1 },{ name:4,type:1 }],
 *   },
 *  {
 *   type:2, values:[ { name:5,type:2 },{ name:6,type:2 }]
 *  },
 *  {
 *   type:10, values:[  { name:7,type:10 }]
 *  }
 * ]
 */
const arrTest = [
	{
		name: 1,
		type: 0,
	},
	{
		name: 2,
		type: 0,
	},
	{
		name: 3,
		type: 1,
	},
	{
		name: 4,
		type: 1,
	},
	{
		name: 5,
		type: 2,
	},
	{
		name: 6,
		type: 2,
	},
	{
		name: 7,
		type: 10,
	},
]

function foo(arr) {
	let res = []
	let map = {}
	//第一次遍历 先构造出基本的数据结构,按照，type进行分组
	arr.forEach((item) => (map[item.type] = { type: item.type, values: [] }))
	// 第二次遍历 将数据 塞到对应的 type 的 values 中
	for (const key in map) {
		if (Object.hasOwnProperty.call(map, key)) {
			const el = map[key]
			arr.forEach((item) => {
				if (item.type === el.type) {
					el.values.push(item)
				}
			})
			//为数组填充组合好的数据
			res.push(el)
		}
	}
	console.log(res)
	return res
}
foo(arrTest)

/**
 * 继承
 */
// 第一种 原型链继承
// function Person() {}
// function Son() {}
// Son.prototype = new Person()
// let s = new Son()
// console.dir(s)

// 第二种 借用构造函数继承
// function Person() {}
// function Son() {
// 	Person.call(this)
// }
// let s = new Son()
// console.dir(s)

// 第三种 组合继承
// function Person() {}
// function Son() {
// 	Person.call(this)
// }
// Son.prototype = new Person()
// let s = new Son()
// console.dir(s)

// 第四种 原型式继承
// function Person() {}
// let s = Object.create(Person.prototype)
// console.dir(s)

//第五中 寄生式继承
// function clone(options) {
// 	let clone = Object.create(options)
// 	clone.personName = 'you'
// 	return clone
// }
// function Person() {}
// let s = clone(Person)
// console.dir(s)

// 第六种 寄生组合式继承
// function inherit(s, p) {
// 	const prototype = Object.create(p.prototype)
// 	s.prototype = prototype
// 	p.construct = s
// }
// function Person() {}
// function Son() {
// 	Person.call(this)
// }
// inherit(Son, Person)
// Son.prototype = new Person()
// let s = new Son()
// console.log(s)

/**
 * 实现一个链式调用
 *
 */
// Number.prototype.add = function (num) {
// 	num = +num
// 	if (num !== num) return Number(this)
// 	return Number(this + num)
// }

// 生成 SQL 语句

// let n = 1
// console.log((1).add(1).add(2).add(3) === 7)

// let str  = '三餐 零食 衣服 交通 旅行 孩子 宠物 花费网费 烟酒 学习 日用品 住房 美妆 医疗 发红包 汽车/加油 娱乐 请客送礼 电器数马 运动 水电 其他'
// let str = "工资 生活费 收红包 外快 股票基金"
// let res =""
// str.split(" ").forEach(item=>{
//   res+=`INSERT INTO order_type (name,type,upt_act) VALUES ('${item}','O','I');`
// })
// console.log(res);
